import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置中文字体为黑体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题
# 1. 创建DataFrame
# 创建一个简单的DataFrame
df1 = pd.DataFrame({
    "a": [4, 5, 6],
    "b": [7, 8, 9],
    "c": [10, 11, 12]
}, index=[1, 2, 3])
print("创建的DataFrame:\n", df1)

# 2. 重塑数据 - 按列值排序
# 按'a'列的值从小到大排序
sorted_df_asc = df1.sort_values('a')
print("按'a'列从小到大排序:\n", sorted_df_asc)
# 按'a'列的值从大到小排序
sorted_df_desc = df1.sort_values('a', ascending=False)
print("按'a'列从大到小排序:\n", sorted_df_desc)

# 3. 重塑数据 - 重命名列
# 将列'b'重命名为'new_b'
renamed_df = df1.rename(columns={'b': 'new_b'})
print("重命名列后的DataFrame:\n", renamed_df)

# 4. 重塑数据 - 排序索引
# 对索引进行排序
sorted_index_df = df1.sort_index()
print("排序索引后的DataFrame:\n", sorted_index_df)

# 5. 重塑数据 - 重置索引
# 重置索引，将原索引变为列
reset_index_df = df1.reset_index()
print("重置索引后的DataFrame:\n", reset_index_df)

# 6. 重塑数据 - 长格式与宽格式转换
# 将宽格式数据转换为长格式
melted_df = pd.melt(df1)
print("转换为长格式后的DataFrame:\n", melted_df)
# 假设melted_df是已经melt后的数据，将长格式数据转换为宽格式
pivoted_df = melted_df.pivot(columns='variable', values='value')
print("转换为宽格式后的DataFrame:\n", pivoted_df)

# 7. 连接DataFrame
# 创建另一个DataFrame用于连接
df2 = pd.DataFrame({
    "a": [7, 8, 9],
    "b": [10, 11, 12],
    "c": [13, 14, 15]
}, index=[4, 5, 6])
# 按行连接
concatenated_rows = pd.concat([df1, df2])
print("按行连接后的DataFrame:\n", concatenated_rows)
# 按列连接
concatenated_cols = pd.concat([df1, df2], axis=1)
print("按列连接后的DataFrame:\n", concatenated_cols)

# 8. 删除列
# 删除'c'列
dropped_df = df1.drop(columns=['c'])
print("删除'c'列后的DataFrame:\n", dropped_df)

# 9. 子集选择 - 选择行
# 选择索引为1到2（不包含2）的行
selected_rows = df1.iloc[1:2]
print("选择索引为1到2（不包含2）的行:\n", selected_rows)
# 根据条件选择行，选择'a'列大于5的行
filtered_rows = df1[df1['a'] > 5]
print("选择'a'列大于5的行:\n", filtered_rows)

# 10. 子集选择 - 选择列
# 选择'b'列
selected_col = df1['b']
print("选择'b'列:\n", selected_col)
# 选择'b'和'c'列
selected_cols = df1[['b', 'c']]
print("选择'b'和'c'列:\n", selected_cols)

# 11. 子集选择 - 按位置选择列
# 选择第1列和第2列（索引从0开始）
selected_cols_by_pos = df1.iloc[:, [0, 1]]
print("选择第1列和第2列:\n", selected_cols_by_pos)

# 12. 子集选择 - 按标签选择列
# 选择索引为'a'到'b'的列（包含'b'）
selected_cols_by_label = df1.loc[:, 'a':'b']
print("选择索引为'a'到'b'的列:\n", selected_cols_by_label)

# 13. 访问单个值
# 通过索引位置访问单个值，第1行第2列（索引从0开始）
single_value_by_index = df1.iat[0, 1]
print("通过索引位置访问单个值:\n", single_value_by_index)
# 通过标签访问单个值，索引为1，列标签为'b'
single_value_by_label = df1.at[1, 'b']
print("通过标签访问单个值:\n", single_value_by_label)

# 14. 使用query方法过滤行
# 选择'a'列大于5的行
filtered_by_query = df1.query('a > 5')
print("使用query方法选择'a'列大于5的行:\n", filtered_by_query)

# 15. 处理缺失数据 - 删除含有缺失值的行
# 创建含有缺失值的DataFrame
df_with_nan = pd.DataFrame({
    "x1": [1, 2, None, 4],
    "x2": ['T', 'F', None, 'T']
})
dropped_nan_df = df_with_nan.dropna()
print("删除含有缺失值的行后的DataFrame:\n", dropped_nan_df)

# 16. 处理缺失数据 - 填充缺失值
# 用0填充缺失值
filled_nan_df = df_with_nan.fillna(0)
print("用0填充缺失值后的DataFrame:\n", filled_nan_df)

# 17. 汇总数据 - 计算唯一值的数量
# 计算'x1'列中唯一值的数量
unique_count = df_with_nan['x1'].nunique()
print("'x1'列中唯一值的数量:\n", unique_count)

# 18. 汇总数据 - 基本描述统计
# 对DataFrame进行基本描述统计
describe_df = df1.describe()
print("基本描述统计:\n", describe_df)

# 19. 计算新列
# 计算新列'd'，其值为'a'列和'b'列之和
new_col_df = df1.assign(d=lambda df: df['a'] + df['b'])
print("计算新列后的DataFrame:\n", new_col_df)

# 20. 分组数据
# 按'a'列进行分组
grouped_df = df1.groupby('a')
# 对分组后的数据计算每组的大小
group_size = grouped_df.size()
print("按'a'列分组后每组的大小:\n", group_size)

# 21. 窗口函数 - 扩展窗口
# 计算扩展窗口的累计和
expanding_sum = df1['a'].expanding().sum()
print("扩展窗口的累计和:\n", expanding_sum)

# 22. 窗口函数 - 滚动窗口
# 计算滚动窗口（窗口大小为2）的平均值
rolling_mean = df1['a'].rolling(2).mean()
print("滚动窗口（窗口大小为2）的平均值:\n", rolling_mean)

# 23. 连接数据集 - 左连接
# 创建两个用于连接的DataFrame
adf = pd.DataFrame({
    "x1": ['A', 'B', 'C'],
    "x2": [1, 2, 3]
})
bdf = pd.DataFrame({
    "x1": ['A', 'B', 'D'],
    "x3": ['T', 'F', 'T']
})
left_joined = pd.merge(adf, bdf, how='left', on='x1')
print("左连接后的DataFrame:\n", left_joined)

# 24. 连接数据集 - 右连接
right_joined = pd.merge(adf, bdf, how='right', on='x1')
print("右连接后的DataFrame:\n", right_joined)

# 25. 连接数据集 - 内连接
inner_joined = pd.merge(adf, bdf, how='inner', on='x1')
print("内连接后的DataFrame:\n", inner_joined)

# 26. 连接数据集 - 外连接
outer_joined = pd.merge(adf, bdf, how='outer', on='x1')
print("外连接后的DataFrame:\n", outer_joined)

# 27. 集合操作 - 差集
# 找出adf中在bdf中没有匹配的行
difference = adf[~adf['x1'].isin(bdf['x1'])]
print("adf中在bdf中没有匹配的行:\n", difference)

# 28. 绘图 - 散点图
# 假设df1中有'w'和'h'列（实际代码中需要根据数据调整）
df1.plot.scatter(x='a', y='b')
plt.title('散点图')
plt.show()

# 29. 绘图 - 直方图
# 为df1的每列绘制直方图
df1.plot.hist()
plt.title('直方图')
plt.show()